package main

import (
    "fmt"
    "github.com/mitchellh/go-homedir"
    "golang.org/x/crypto/ssh"
    "io/ioutil"
    "log"
    "time"
)

func main() {
    sshHost:= "47.100.237.45"
    sshUser := "root"
    sshPassword := "NewJb$LvbeX2R"
    sshType := "password"
    sshKeyPath := ""
    sshPort := 22

    //创建 ssh 登陆配置
    config := &ssh.ClientConfig{
        Timeout: time.Second,//ssh 连接 time out 时间一秒钟，如果ssh 验证错误会在一秒内返回
        User:    sshUser,
        HostKeyCallback: ssh.InsecureIgnoreHostKey(), // 这个可以，但是不够安全
        // HostKeyCallback: hostKeyCallBackFunc(h.Host),
    }
    if sshType == "password" {
        config.Auth = []ssh.AuthMethod{ssh.Password(sshPassword)}
    } else {
        config.Auth = []ssh.AuthMethod{publicKeyAuthFunc(sshKeyPath)}
    }

    //dial 获取ssh client
    addr := fmt.Sprintf("%s:%d", sshHost, sshPort)
    sshClient, err := ssh.Dial("tcp", addr, config)
    if err != nil {
        log.Fatal("创建ssh client 失败", err)
    }
    defer sshClient.Close()
    
    //创建ssh-session
    session, err := sshClient.NewSession()
    if err != nil {
        log.Fatal("创建ssh session 失败", err)
    }
    defer session.Close()

    //执行远程命令
    combo,err := session.CombinedOutput("whoami; pwd; ls -al")
    if err != nil {
        log.Fatal("远程执行cmd 失败", err)
    }
    log.Println("命令输出：", string(combo))

    // 延时（为了打包后的界面更友好）
    nowTime := time.Now()
    time.Sleep(2 * time.Second)
    latency := time.Since(nowTime).Seconds()
    fmt.Println(latency)
    fmt.Println("The End")
}

func publicKeyAuthFunc(kPath string) ssh.AuthMethod {
    keyPath, err := homedir.Expand(kPath)
    if err != nil {
        log.Fatal("find key's home dir failed", err)
    }
    key, err := ioutil.ReadFile(keyPath)
    if err != nil {
        log.Fatal("ssh key file read failed", err)
    }
    // Create the Signer for this private key.
    signer, err := ssh.ParsePrivateKey(key)
    if err != nil {
        log.Fatal("ssh key signer failed", err)
    }
    return ssh.PublicKeys(signer)
}
